home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Java 1996 August
/
Java - Summer 1996.iso
/
kaffe-0.2
/
kaffe
/
findClass.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-13
|
3KB
|
158 lines
/*
* findClass.c
* Search the CLASSPATH for the given class name.
*
* Copyright (c) 1996 Systems Architecture Research Centre,
* City University, London, UK.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
*/
#define ZDBG(s)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include "errors.h"
#include "file.h"
#include "zipfile.h"
#define CLASSPATH "CLASSPATH"
#define MAXBUF 256
#define MAXPATHELEM 16
#define MAXPATHLEN 256
#define CP_INVALID 0
#define CP_FILE 1
#define CP_DIR 2
static struct {
int type;
char* path;
} classpath[MAXPATHELEM+1];
static char realClassPath[MAXPATHLEN];
void initClasspath(void);
/*
* Find the named class in a directory or zip file.
*/
void
findClass(char* cname)
{
char* cp;
int i;
char buf[MAXBUF];
int fp;
struct stat sbuf;
classFile hand;
ZipFile zipf;
ZipDirectory *zipd;
int r;
int j;
/* Look for the class */
for (i = 0; classpath[i].path != 0; i++) {
switch (classpath[i].type) {
case CP_FILE:
ZDBG( printf("Opening zip file %s for %s\n", classpath[i].path, cname); )
strcpy(buf, cname);
strcat(buf, ".class");
fp = open(classpath[i].path, O_RDONLY);
zipf.fd = fp;
if (fp < 0 || read_zip_archive (&zipf) != 0) {
continue;
}
zipd = (ZipDirectory*)zipf.central_directory;
for (j = 0; j < zipf.count; j++, zipd = ZIPDIR_NEXT(zipd)) {
ZDBG( printf ("%d: size:%d, name(#%d)%s, offset:%d\n", i, zipd->size,
zipd->filename_length, ZIPDIR_FILENAME (zipd), zipd->filestart); )
if (strcmp(buf, ZIPDIR_FILENAME(zipd)) == 0) {
ZDBG( printf("FOUND!!\n"); )
lseek(fp, zipd->filestart, SEEK_SET);
hand.size = zipd->size;
free(zipf.central_directory);
goto found;
}
}
free(zipd);
close(fp);
continue;
case CP_DIR:
strcpy(buf, classpath[i].path);
strcat(buf, "/");
strcat(buf, cname);
strcat(buf, ".class");
fp = open(buf, O_RDONLY);
if (fp < 0 || fstat(fp, &sbuf) < 0) {
continue;
}
hand.size = sbuf.st_size;
found:
hand.base = malloc(hand.size);
hand.buf = hand.base;
if (hand.buf == 0) {
throwException(OutOfMemoryError);
}
if (read(fp, hand.buf, hand.size) != hand.size) {
abort();
}
close(fp);
readClass(&hand);
free(hand.base);
break;
}
return;
}
throwException(NoClassDefFoundError);
}
/*
* Initialise class path.
*/
void
initClasspath(void)
{
struct stat sbuf;
char* cp;
int i;
int fd;
cp = getenv(CLASSPATH);
if (cp == 0) {
fprintf(stderr, "CLASSPATH is not set!\n");
exit(1);
}
strcpy(realClassPath, cp);
cp = realClassPath;
for (i = 0; cp != 0 && i < MAXPATHELEM; i++) {
classpath[i].path = cp;
cp = strchr(cp, ':');
if (cp != 0) {
*cp = 0;
cp++;
}
if (stat(classpath[i].path, &sbuf) < 0) {
classpath[i].type = CP_INVALID;
}
else if (S_ISDIR(sbuf.st_mode)) {
classpath[i].type = CP_DIR;
}
else {
classpath[i].type = CP_FILE;
}
}
i++;
classpath[i].path = 0;
}